package com.example.config;
 import com.example.filter.JwtAuthenticationTokenFilter;
 import com.example.handler.AnonymousAuthenticationHandler;
 import com.example.handler.CustomerAccessDeniedHandler;
 import com.example.handler.LoginFailureHandler;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.security.authentication.AuthenticationManager;
 import org.springframework.security.config.Customizer;
 import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
 import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
 import org.springframework.security.config.annotation.web.configurers.ExceptionHandlingConfigurer;
 import org.springframework.security.config.annotation.web.configurers.FormLoginConfigurer;
 import org.springframework.security.config.http.SessionCreationPolicy;
 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
 import org.springframework.security.crypto.password.PasswordEncoder;
 import org.springframework.security.web.SecurityFilterChain;
 import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
 public class SecurityConfig{
    //自定义用于认证的过滤器，进行jwt的校验操作
    @Autowired
    private JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;
    //认证用户无权限处理器
    @Autowired
    private CustomerAccessDeniedHandler customerAccessDeniedHandler;
    //客服端进行认证数据的提交，匿名用户访问无权限资源的处理类
    @Autowired
    private AnonymousAuthenticationHandler anonymousAuthenticationHandler;
    //用户认证校验失败处理器
    @Autowired
    private LoginFailureHandler loginFailureHandler;

        //创建BCryptPasswordEncoder注入容器
        @Bean
        public PasswordEncoder passwordEncoder(){
            return new BCryptPasswordEncoder();
        }

     /**
      *登录需要调用AuthenticationManager.authenticate执行异常校验
      *
      */
        @Bean
       public AuthenticationManager
       authenticationManager(AuthenticationConfiguration config) throws Exception {
         return config.getAuthenticationManager();
       }

       //登录请求放行
       @Bean
       public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
           //配置关闭csrf机制
           http.csrf(csrf -> csrf.disable());

           //用户认证校验失败处理器
           http.formLogin(configurer -> configurer.failureHandler(loginFailureHandler));

           //permitAll:随意访问
           //表示程序是无状态的，不会创建会话
           http.sessionManagement(configurer ->
                   configurer.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
           );
           //配置请求拦截方式
           http.authorizeHttpRequests(auth -> auth.requestMatchers("/user/login")
                   .permitAll()
                   .anyRequest()
                   .authenticated());
           //把token校验过滤器添加到过滤器链中
           http.addFilterBefore(jwtAuthenticationTokenFilter,
                   UsernamePasswordAuthenticationFilter.class);
           http.addFilterBefore(jwtAuthenticationTokenFilter,
                   UsernamePasswordAuthenticationFilter.class);
           //配置自定义的异常处理器(也可以用链式编程一行写完）
           http.exceptionHandling(configurer -> {configurer.accessDeniedHandler(customerAccessDeniedHandler).authenticationEntryPoint(anonymousAuthenticationHandler);
                       configurer.authenticationEntryPoint(anonymousAuthenticationHandler);
           });
           return http.build();
       }
}